package com.atguigu.classroom.order.service.impl;

import com.atguigu.classroom.ActivityClient.CouponFeignClient;
import com.atguigu.classroom.CourseClient.CourseFeignClient;
import com.atguigu.classroom.exception.ClassroomException;
import com.atguigu.classroom.model.activity.CouponInfo;
import com.atguigu.classroom.model.order.OrderDetail;
import com.atguigu.classroom.model.order.OrderInfo;
import com.atguigu.classroom.model.user.UserInfo;
import com.atguigu.classroom.model.vod.Course;
import com.atguigu.classroom.order.mapper.OrderDetailMapper;
import com.atguigu.classroom.order.mapper.OrderInfoMapper;
import com.atguigu.classroom.order.service.OrderInfoService;
import com.atguigu.classroom.userClient.UserInfoFeignClient;
import com.atguigu.classroom.utils.AuthContextHolder;
import com.atguigu.classroom.utils.OrderNoUtils;
import com.atguigu.classroom.vo.order.OrderFormVo;
import com.atguigu.classroom.vo.order.OrderInfoQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 订单表 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2022-07-16
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CouponFeignClient couponFeignClient;//引用远程调用接口
    @Autowired
    private CourseFeignClient courseFeignClient;//引用远程调用接口
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;//引用远程调用接口

    @Override
    public Page<OrderInfo> getPage(int page, int limit, OrderInfoQueryVo orderInfoQueryVo) {
        Page<OrderInfo> orderInfoPage=new Page<>(page,limit);
        LambdaQueryWrapper<OrderInfo> orderInfoQueryWrapper=new LambdaQueryWrapper<>();
        orderInfoQueryWrapper.eq(orderInfoQueryVo.getUserId()!=null,OrderInfo::getUserId,orderInfoQueryVo.getUserId())
                .like(orderInfoQueryVo.getNickName()!=null,OrderInfo::getNickName,orderInfoQueryVo.getNickName())
                .like(orderInfoQueryVo.getPhone()!=null,OrderInfo::getPhone,orderInfoQueryVo.getPhone())
                .eq(orderInfoQueryVo.getOrderStatus()!=null,OrderInfo::getOrderStatus,orderInfoQueryVo.getOrderStatus())
                .like(orderInfoQueryVo.getOutTradeNo()!=null,OrderInfo::getOutTradeNo,orderInfoQueryVo.getOutTradeNo())
                .eq(orderInfoQueryVo.getProvince()!=null,OrderInfo::getProvince,orderInfoQueryVo.getProvince())
                .ge(orderInfoQueryVo.getCreateTimeBegin()!=null,OrderInfo::getCreateTime,orderInfoQueryVo.getCreateTimeBegin())
                .le(orderInfoQueryVo.getCreateTimeEnd()!=null,OrderInfo::getCreateTime,orderInfoQueryVo.getCreateTimeEnd());
        orderInfoMapper.selectPage(orderInfoPage,orderInfoQueryWrapper);//sql-1:查询订单大纲
        if (orderInfoPage.getRecords().size()==0){
            return orderInfoPage;
        }
        List<Long> orderIds=orderInfoPage.getRecords().stream().map(orderInfo -> {
            Long id = orderInfo.getId();
            return id;
        }).collect(Collectors.toList());
        LambdaQueryWrapper<OrderDetail> orderDetailQueryWrapper=new LambdaQueryWrapper<>();
        orderDetailQueryWrapper.in(OrderDetail::getOrderId,orderIds);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(orderDetailQueryWrapper);//sql-2:查询订单详情
        Map<Long,OrderDetail> orderDetailMap=new HashMap<>(orderDetails.size());
        for(OrderDetail orderDetail:orderDetails){
            orderDetailMap.put(orderDetail.getOrderId(),orderDetail);
        }
        List<OrderInfo> records=orderInfoPage.getRecords().stream().map(orderInfo -> {
            OrderInfo newOrderInfo=new OrderInfo();
            BeanUtils.copyProperties(orderInfo,newOrderInfo);
            newOrderInfo.getParam().put("courseName",orderDetailMap.get(orderInfo.getId()).getCourseName());
            return newOrderInfo;
        }).collect(Collectors.toList());
        orderInfoPage.setRecords(records);
        return orderInfoPage;
    }

    @Override
    @Transactional
    public Long submitOrder(OrderFormVo orderFormVo) {
        /* 1、判断当前用户是否已经生成订单
         * 2、根据相关信息查询课程信息，用户信息，优惠劵信息(远程调用)
         * 3、完成order_detail表和order_info表添加操作
         * 4、更新优惠劵状态(远程调用)并返回订单id*/
        Long userId = AuthContextHolder.getUserId();//当前微信登陆用户的id
        LambdaQueryWrapper<OrderDetail> orderDetailQueryWrapper=new LambdaQueryWrapper<>();
        orderDetailQueryWrapper.eq(OrderDetail::getUserId,userId)
          .eq(OrderDetail::getCourseId,orderFormVo.getCourseId());
        OrderDetail oldOrderDetail = orderDetailMapper.selectOne(orderDetailQueryWrapper);
        //sql-1:查询是否曾经有订单
        if(oldOrderDetail!=null){
            return oldOrderDetail.getOrderId();
        }
        Course course = courseFeignClient.getById(orderFormVo.getCourseId());
        //sql-2:查询课程信息--远程调用
        if (course==null){
            throw new ClassroomException(20001,"课程不存在");
        }
        List<UserInfo> userInfos = userInfoFeignClient.getByIds(Collections.singletonList(userId));
        //sql-3:查询用户信息--远程调用
        if (userInfos.get(0)==null){
            throw new ClassroomException(20001,"用户不存在");
        }
        BigDecimal couponReduce=new BigDecimal(0);
        if(orderFormVo.getCouponId()!=null){
            CouponInfo couponInfo = couponFeignClient.getById(orderFormVo.getCouponId());
            //sql-4:查询优惠卷信息--远程调用
            couponReduce=couponInfo.getAmount();
        }
        /*生成订单基本信息*/
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setNickName(userInfos.get(0).getNickName());
        orderInfo.setPhone(userInfos.get(0).getPhone());
        orderInfo.setProvince(userInfos.get(0).getProvince());
        orderInfo.setOriginAmount(course.getPrice());
        orderInfo.setCouponReduce(couponReduce);
        orderInfo.setFinalAmount(course.getPrice().subtract(couponReduce));
        orderInfo.setOutTradeNo(OrderNoUtils.getOrderNo());
        orderInfo.setTradeBody(course.getTitle());
        orderInfo.setOrderStatus("0");
        orderInfoMapper.insert(orderInfo);//sql-5:插入订单基本信息
        /*生成订单详细信息*/
        OrderDetail orderDetail=new OrderDetail();
        orderDetail.setOrderId(orderInfo.getId());
        orderDetail.setUserId(userId);
        orderDetail.setCourseId(orderFormVo.getCourseId());
        orderDetail.setCourseName(course.getTitle());
        orderDetail.setCover(course.getCover());
        orderDetail.setOriginAmount(course.getPrice());
        orderDetail.setCouponReduce(couponReduce);
        orderDetail.setFinalAmount(course.getPrice().subtract(couponReduce));
        orderDetailMapper.insert(orderDetail);//sql-6:插入订单详细信息
        if(orderFormVo.getCouponId()!=null){
            couponFeignClient.updateCouponInfoUseStatus(orderFormVo.getCouponUseId(),orderInfo.getId());
        }//sql-7:更新优惠劵状态--远程调用
        return orderInfo.getId();
    }
}
